﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SharpObjects.Interfaces;
using SharpObjects.Configuration;
using SharpObjects.Configuration.ConfigurationProviders;
using SharpObjects.RuleEngine;
using SharpObjects.RuleEngine.RuleElements;

namespace SharpObjects.RuleEngine.Rules
{
    public class ConcatenateStringsRule : IXmlInitializable, IRule
    {
        public string Delimiter { get; set; }
        public string Output { get; set; }
        public bool SkipIfEmpty { get; set; }
        public object[] Fields { get; set; }

        public ConcatenateStringsRule()
        {
            Delimiter = string.Empty;
        }

        #region IInitializable Members

        public void Initialize(System.Xml.XmlElement initializationElement)
        {
            XmlConfigurationProvider init = new XmlConfigurationProvider(initializationElement);
            
            Delimiter = init.GetString("@delimiter", string.Empty);
            Output = init.GetString("@output");
            SkipIfEmpty = init.GetBoolean("@skip_if_empty", true);
            Fields = init.GetObjects<object>("field | value");

            this.IsInitialized = true;
        }

        public bool IsInitialized { get; set; }

        #endregion

        #region IRule Members

        public void Execute(ref IRuleEngineContext ruleEngineContext, IDataProvider dataProvider)
        {
            StringBuilder sb = new StringBuilder();

            for(int k = 0; k < Fields.Length; k++)
            {
                string value;

                if (Fields[k] is FieldElement)
                {
                    FieldElement field = (FieldElement)Fields[k];
                    value = field.GetValue(ruleEngineContext, dataProvider).ToString();
                }
                else
                {
                    ValueElement valEl = (ValueElement)Fields[k];
                    value = valEl.Value.ToString();
                }

                if (value != string.Empty)
                {
                    sb.Append(value);

                    if (k < (Fields.Length - 1))
                    {
                        sb.Append(Delimiter);
                    }
                }
                else
                {
                    if (!SkipIfEmpty)
                    {
                        //if (k < (Fields.Length - 1))
                        {
                            sb.Append(Delimiter);
                        }
                    }
                }
            }

            ruleEngineContext.SetValue<string>(Output, sb.ToString());
        }

        #endregion
    }
}
